import { JSONSchemaType } from "ajv";
import { IMiddleware } from "koa-router";

import { Admin } from "../model";
import { validateBody } from "../middleware/validate";
import { makeResponse, HttpStatusCode } from "../util/response";
import { ajv } from "../util/ajv";
import md5 from "../util/md5";

interface Login {
  username: string;
  password: string;
}

interface Register {
  username: string;
  password: string;
  email: string;
}

const loginSchema: JSONSchemaType<Login> = {
  type: "object",
  properties: {
    username: {
      type: "string",
      isNotEmpty: true
    },
    password: {
      type: "string",
      isNotEmpty: true
    }
  },
  required: ["username", "password"]
};
ajv.addSchema(loginSchema, "Login");

const registerSchema: JSONSchemaType<Register> = {
  type: "object",
  properties: {
    username: {
      type: "string",
      isNotEmpty: true
    },
    password: {
      type: "string",
      isNotEmpty: true
    },
    email: {
      type: "string",
      isNotEmpty: true,
      format: "email",
      errorMessage: {
        format: "email 格式不正确"
      }
    }
  },
  required: ["username", "password", "email"]
};
ajv.addSchema(registerSchema, "Register");

export const loginValidator: IMiddleware[] = [
  // 数据基本校验
  validateBody("Login"),
  // 获取数据库信息
  async (ctx, next) => {
    const { username, password } = ctx.request.body;
    const admin = await Admin.findOne({ username }).select(
      "username password status articles name"
    );
    if (!admin) makeResponse(ctx, HttpStatusCode.BadRequest, "用户名或密码错误，请重试");
    else if (md5(password) !== admin?.password)
      makeResponse(ctx, HttpStatusCode.BadRequest, "用户名或密码错误，请重试");
    else {
      // 将 admin 对象传递到下一个中间件使用
      ctx.state.admin = admin;
      await next();
    }
  }
];

export const registerValidator: IMiddleware[] = [
  // 数据基本校验
  validateBody("Register"),
  // 获取数据库对比校验
  async (ctx, next) => {
    const { username } = ctx.request.body;
    const admin = await Admin.findOne({ username });
    if (admin) makeResponse(ctx, HttpStatusCode.BadRequest, "用户名已存在");
    else await next();
  }
];
